package socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;

import socket.body.ApplyKey;

import cn.ccb.puresecapi.PureSecAPI;
import cn.ccb.puresecapi.PureSecException;

public class SocketClient {
	private static final Logger log = Logger.getLogger(SocketClient.class);
	/** 服务器地址 */
	private String hostName;
	/** 端口号 */
	private int portNum;
	/** 接收返回报文延时 */
	private int delaySecond;

	public SocketClient() {
		// this.hostName = "10.187.6.193";
		this.hostName = "127.0.0.1";
		this.portNum = 5678;
		// this.portNum = 60000;
		this.delaySecond = 35000;
	}

	/** 创建Socket连接主机 */
	private Socket getSocket() {
		Socket socket = null;
		try {
			socket = new Socket(hostName, portNum);
			socket.setSoTimeout(delaySecond);
		} catch (UnknownHostException e) {
			System.out.println("-->未知的主机名:" + hostName + " 异常");
			log.info("-->未知的主机名:" + hostName + " 异常");
		} catch (IOException e) {
			System.out.println("-hostName=" + hostName + " portNum=" + portNum + "---->IO异常错误" + e.getMessage());
			log.info("-hostName=" + hostName + " portNum=" + portNum + "---->IO异常错误" + e.getMessage());
		}
		return socket;
	}

	/** 发送并接受数据 */
	@SuppressWarnings("finally")
	public String sendMessage(String strMessage) {

		//return test1(strMessage);
		return test2(strMessage);
	}

	@SuppressWarnings("finally")
	private String test1(String strMessage) {
		/** 返回接收数据或错误代码 */
		String str = "";
		Socket socket = null;
		// long sendTime = System.currentTimeMillis();
		// long receiveTime = System.currentTimeMillis();
		boolean received = false; // 成功接收报文
		// boolean delayTooLong = false;
		PrintWriter out = null;
		BufferedReader in = null;
		try {
			socket = getSocket();
			// 未能得到指定的Socket对象,Socket通讯为空
			if (socket == null) {
				return "nullerror";
			}

			// 由Socket对象得到输出流，并构造PrintWriter对象
			out = new PrintWriter(socket.getOutputStream());

			out.println(strMessage);
			// 刷新使的服务端立即接受数据
			out.flush();
			// 接收应答
			InputStreamReader isr = new InputStreamReader(socket.getInputStream(), "GBK");
			in = new BufferedReader(isr);
			// BufferedInputStream ins = new
			// BufferedInputStream(socket.getInputStream());
			try {
				char[] charBuf = new char[130];
				int len = in.read(charBuf);
				str = new String(charBuf, 0, len);
				System.out.println("Server say : 总长度" + str.getBytes().length + "内容：" + str);
				log.info("Server say : 总长度" + str.getBytes().length + "内容：" + str);
				if (str != null) {
					// 返回接受数据
					received = true;
				}
			} catch (SocketTimeoutException e) {
				str = "timeout";
				System.out.println("Time out, No response");
				log.info("Time out, No response");
			}

			/*
			 * while (!received && !delayTooLong) { receiveTime =
			 * System.currentTimeMillis(); if ((receiveTime - sendTime) >
			 * delaySecond) delayTooLong = true; // 接收等待时间过长，超时 } if
			 * (delayTooLong) str="timeout"; //超时标志为真，返回超时码
			 */
			if (!received)
				str = "timeout";
		} catch (UnknownHostException e) {
			System.out.println(
					"---->出现未知主机错误! 主机信息=" + this.hostName + " 端口号=" + this.portNum + " 出错信息=" + e.getMessage());
			log.info("---->出现未知主机错误! 主机信息=" + this.hostName + " 端口号=" + this.portNum + " 出错信息=" + e.getMessage());
			str = "UnhostNameerror";
		} catch (IOException e) {
			System.out
					.println("---->出现IO异常! 主机信息=" + this.hostName + " 端口号=" + this.portNum + " 出错信息=" + e.getMessage());
			log.info("---->出现IO异常! 主机信息=" + this.hostName + " 端口号=" + this.portNum + " 出错信息=" + e.getMessage());
			e.printStackTrace();
			str = "IOerror";
		} catch (Exception e) {
			str = "unerror";
			System.out.println("---->出现未知异常" + e.getMessage());
			log.info("---->出现未知异常" + e.getMessage());
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (Exception ex) {
					ex.printStackTrace();
				}
			}
			if (in != null) {
				try {
					in.close();
				} catch (Exception ex) {
					ex.printStackTrace();
				}
			}
			if (socket != null) {
				try {
					socket.close();
				} catch (Exception ex) {
					ex.printStackTrace();
				}
			}
			return str;
		}
	}

	@SuppressWarnings("finally")
	private String test2(String strMessage) {
		/** 返回接收数据或错误代码 */
		String str = "";
		Socket socket = null;
		boolean received = false; // 成功接收报文
		OutputStream out = null;
		InputStream in = null;
		try {
			socket = getSocket();
			// 未能得到指定的Socket对象,Socket通讯为空
			if (socket == null) {
				return "nullerror";
			}
			out = socket.getOutputStream();
			in = socket.getInputStream();
			// 密码加密算法
			final int alg = 2;
			// 密钥散列因子
			byte[] factor = "001982201603251058928".getBytes();
			// 加密处理
			byte[] sendmsg = PureSecAPI.pkgCrypto(0, alg, strMessage.getBytes(), factor);

			out.write(sendmsg);
			out.flush();
			// 接收应答
			try {
				byte[] charBuf = new byte[4096];
				int size = 0;
				size = in.read(charBuf, 0, 4096);
				for (int i = 0; i < charBuf.length; i++) {
					System.out.print(charBuf[i]);
				}
				byte[] resvmsg = PureSecAPI.pkgCrypto(1, alg, charBuf, factor);
				str=new String(resvmsg);
				System.out.println("Server say : 总长度" + resvmsg.length + "内容：" + str);
				log.info("Server say : 总长度" + resvmsg.length + "内容：" + str);
				if (str != null) {
					// 返回接受数据
					received = true;
				}
			} catch (SocketTimeoutException e) {
				str = "timeout";
				System.out.println("Time out, No response");
				log.info("Time out, No response");
			}

			/*
			 * while (!received && !delayTooLong) { receiveTime =
			 * System.currentTimeMillis(); if ((receiveTime - sendTime) >
			 * delaySecond) delayTooLong = true; // 接收等待时间过长，超时 } if
			 * (delayTooLong) str="timeout"; //超时标志为真，返回超时码
			 */
			if (!received)
				str = "timeout";
		} catch (UnknownHostException e) {
			System.out.println(
					"---->出现未知主机错误! 主机信息=" + this.hostName + " 端口号=" + this.portNum + " 出错信息=" + e.getMessage());
			log.info("---->出现未知主机错误! 主机信息=" + this.hostName + " 端口号=" + this.portNum + " 出错信息=" + e.getMessage());
			str = "UnhostNameerror";
		} catch (IOException e) {
			System.out
					.println("---->出现IO异常! 主机信息=" + this.hostName + " 端口号=" + this.portNum + " 出错信息=" + e.getMessage());
			log.info("---->出现IO异常! 主机信息=" + this.hostName + " 端口号=" + this.portNum + " 出错信息=" + e.getMessage());
			e.printStackTrace();
			str = "IOerror";
		} catch (Exception e) {
			str = "unerror";
			System.out.println("---->出现未知异常" + e.getMessage());
			log.info("---->出现未知异常" + e.getMessage());
		} 
		return str;
		//finally {
//			if (out != null) {
//				try {
//					out.close();
//				} catch (Exception ex) {
//					ex.printStackTrace();
//				}
//			}
//			if (in != null) {
//				try {
//					in.close();
//				} catch (Exception ex) {
//					ex.printStackTrace();
//				}
//			}
//			if (socket != null) {
//				try {
//					socket.close();
//				} catch (Exception ex) {
//					ex.printStackTrace();
//				}
//			}
//			return str;
//		}
	}

	public static void main(String[] args) throws UnsupportedEncodingException {
		SocketClient s = new SocketClient();
		Header header = new Header();
		ApplyKey applyKey = new ApplyKey();
		String str = HeaderStr.getBodyStr(applyKey);
		// str.getBytes("UTF-8");
		String strw = s.sendMessage(str);
		strw = strw.substring(0, strw.length());
		System.out.println("报文体：" + strw);
		System.out.println("报文体长度：" + strw.length());
		String[] arr = HeaderStr.getBody(strw);
		for (String string : arr) {
			System.out.println(string);
		}
	}
}
